package com.raspberryCar.model;

import com.pi4j.gpio.extension.pca.PCA9685Pin;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.GpioPinPwmOutput;
import com.pi4j.io.gpio.Pin;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.util.CommandArgumentParser;

/**
 * 小车控制类，包含一个直流电机和一个舵机的操作
 * 
 * @author huyong
 *
 */
public class Car extends ServoMotor {
	// 定义舵机转动的角度
	private static final int[] angles = { 850, 1050, 1250, 1350, 1450, 1650,
			1850 };
	// 经测试anges=1350时，舵机方向正好在中间
	private static int position = 3;

	// 接L298n的输入控制端
	static GpioPinDigitalOutput pinOutput24;
	static GpioPinDigitalOutput pinOutput25;
	static int speed = 20;
	// 0表示前进，1表示后退
	static int toward = 0;
	// 树莓派本身的pwm 接口，用于L298n驱动板使能端控制
	static GpioPinPwmOutput pwm;
	private static Car car;

	private Car() {

		Pin pin8 = CommandArgumentParser.getPin(RaspiPin.class, // pin provider
																// class to
																// obtain pin
																// instance from
				RaspiPin.GPIO_24); // default pin if no pin argument found

		Pin pin9 = CommandArgumentParser.getPin(RaspiPin.class, // pin provider
																// class to
																// obtain pin
																// instance from
				RaspiPin.GPIO_25); // default pin if no pin argument found
		pinOutput24 = gpio.provisionDigitalOutputPin(pin8, "MyLED",
				PinState.LOW);
		pinOutput25 = gpio.provisionDigitalOutputPin(pin9, "MyLED",
				PinState.LOW);
		Pin pin = CommandArgumentParser.getPin(RaspiPin.class, // pin provider
																// class to
																// obtain pin
																// instance from
				RaspiPin.GPIO_23); // default pin if no pin argument found

		pwm = gpio.provisionPwmOutputPin(pin);
		pwm.setPwmRange(100);
		//
		// 舵机中间位置
		gpioProvider.setPwm(PCA9685Pin.PWM_02, 1350);
	}

	public static Car getInstance() {
		if (car == null) {
			car = new Car();
		}
		return car;
	}

	/**
	 * 左转弯
	 */
	public void left() {
		System.out.println("left:" + position);

		if (position - 1 >= 0) {
			position = position - 1;
			gpioProvider.setPwm(PCA9685Pin.PWM_02, angles[position]);
		}
		// motor.setAngle(0);
		System.out.println("done");

	}

	/**
	 * 右转弯
	 */
	public void right() {
		System.out.println("right:" + position);

		if (position + 1 <= 6) {
			position = position + 1;
			gpioProvider.setPwm(PCA9685Pin.PWM_02, angles[position]);
		}
		// motor.setAngle(angles[7]);
		System.out.println("done");
	}

	/**
	 * 倒车
	 */
	public void ret() {
		if (toward == 1) {
			if (speed <= 80) {
				speed += 20;
			}

			pinOutput24.setState(PinState.HIGH);
			pinOutput25.setState(PinState.LOW);
		} else if (toward == 0 && speed == 0) {
			toward = 1;
			speed = 20;
			pinOutput24.setState(PinState.HIGH);
			pinOutput25.setState(PinState.LOW);
		} else {
			if (speed >= 20) {
				speed -= 20;
			}
		}
		pwm.setPwm(speed);
		System.out.println("retreat:" + speed + ", toward:" + toward);
	}

	/**
	 * 前进
	 */
	public void faw() {
		if (toward == 0) {
			if (speed <= 80) {
				speed += 20;
			}

			pinOutput24.setState(PinState.LOW);
			pinOutput25.setState(PinState.HIGH);
		} else if (toward == 1 && speed == 0) {
			toward = 0;
			speed = 20;
			pinOutput24.setState(PinState.LOW);
			pinOutput25.setState(PinState.HIGH);
		} else {
			if (speed >= 20) {
				speed -= 20;
			}
		}
		pwm.setPwm(speed);
		System.out.println("faw:" + speed + ", toward:" + toward);
	}

	/**
	 * 停止
	 */
	public void stop() {
		if (toward == 1) {
			pinOutput24.setState(PinState.LOW);
			pinOutput25.setState(PinState.HIGH);
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} else {
			pinOutput24.setState(PinState.HIGH);
			pinOutput25.setState(PinState.LOW);
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		pinOutput24.setState(PinState.HIGH);
		pinOutput25.setState(PinState.HIGH);
		speed = 0;
		pwm.setPwm(speed);
		System.out.println("stop");
	}

	/**
	 * 加速
	 */
	public void fast() {
		if (speed < 100) {
			speed += 10;
		}

		pwm.setPwm(speed);
		System.out.println("fast:" + speed);
	}

	/**
	 * 减速
	 */
	public void slow() {
		if (speed > 20) {
			speed -= 10;
		}
		pwm.setPwm(speed);
		System.out.println("fast:" + speed);
	}

	public int getPosition() {
		return position;
	}

	public void setPosition(int position) {
		Car.position = position;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		Car.speed = speed;
	}

	public int getToward() {
		return toward;
	}

	public void setToward(int toward) {
		Car.toward = toward;
	}

}
